/*
 *  DynamicArray.c
 *  Lec2Assignments
 *
 *  Created by Daniel Lin on 12/20/10.
 *  Copyright 2010 __MyCompanyName__. All rights reserved.
 *
 */

#include "DynamicArray.h"

#define DEFAULT_ARRAY_CAPACITY		128


/*
 *	InitDynamicArray
 */
#define IMPLEMENT_FUNC_INITARRAY(T)							\
void _INIT_##T##ARRAY(Dynamic_##T##Array* thisPointer)	{	\
	thisPointer->push_back		= _PUSH_BACK_##T##_;		\
	thisPointer->popup			= _POPUP_##T##_;			\
	thisPointer->objectAtIndex	= _OBJECT_##T##_ATINDEX;	\
	thisPointer->_buf			= malloc(DEFAULT_ARRAY_CAPACITY * sizeof(T));\
	thisPointer->_top			= thisPointer->_buf;		\
	thisPointer->_bottom		= thisPointer->_buf;		\
															\
															\
	thisPointer->_capacity	= DEFAULT_ARRAY_CAPACITY;		\
}	

/*
 *	PushBack
 */
#define IMPLEMENT_FUNC_PUSHBACK(T) \
static void _PUSH_BACK_##T##_(Dynamic_##T##Array* thisPointer,T* object) {											\
	printf("%s\n",__func__);																						\
	if(object != NULL) {																							\
		/*while (*object != '\0' )*/ {																					\
			if(thisPointer->_top + 1 - thisPointer->_bottom >= thisPointer->_currentBufSize) {						\
				thisPointer->_currentBufSize	= (thisPointer->_currentBufSize + DEFAULT_ARRAY_CAPACITY*sizeof(T));\
				thisPointer->_buf				= realloc(thisPointer->_buf,thisPointer->_currentBufSize*sizeof(T));\
				thisPointer->_top				= thisPointer->_buf + (thisPointer->_top - thisPointer->_bottom);	\
				thisPointer->_bottom			= thisPointer->_buf;						}						\
		}																											\
		*(thisPointer->_top)++ = *object++;																			\
	}																												\
}



/**
 *	PopUp
 */
#define IMPLEMENT_FUNC_POPUP(T) \
static T _POPUP_##T##_(Dynamic_##T##Array* thisPointer) {															\
	printf("%s\n",__func__);																						\
	T retVal;																										\
	if(thisPointer->_top - thisPointer->_bottom > 0) {																\
		retVal = *(thisPointer->_top);																				\
		thisPointer->_top--;																						\
	}																												\
	return retVal;																									\
}

/**
 *	ObjectAtIndex
 */
#define IMPLEMENT_FUNC_OBJECTATINDEX(T) \
static T _OBJECT_##T##_ATINDEX(Dynamic_##T##Array* thisPointer,unsigned int index) {								\
	printf("%s\n",__func__);																						\
	T retVal;																										\
	if(thisPointer->_top - thisPointer->_bottom > index) {															\
		retVal = *(thisPointer->_bottom + index);																	\
	}																												\
	return retVal;																									\
}

IMPLEMENT_FUNC_INITARRAY(char)
IMPLEMENT_FUNC_POPUP(char)
IMPLEMENT_FUNC_PUSHBACK(char)
IMPLEMENT_FUNC_OBJECTATINDEX(char)

IMPLEMENT_FUNC_INITARRAY(float)
IMPLEMENT_FUNC_POPUP(float)
IMPLEMENT_FUNC_PUSHBACK(float)
IMPLEMENT_FUNC_OBJECTATINDEX(float)

IMPLEMENT_FUNC_INITARRAY(int)
IMPLEMENT_FUNC_POPUP(int)
IMPLEMENT_FUNC_PUSHBACK(int)
IMPLEMENT_FUNC_OBJECTATINDEX(int)